package com.mallcai.bigdata.ladon.service.report.impl;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.dpl.entity.report.Group;
import com.mallcai.bigdata.ladon.dpl.mapper.report.GroupMapper;
import com.mallcai.bigdata.ladon.service.report.IGroupService;
import com.mallcai.bigdata.ladon.vo.Pair;
import com.mallcai.bigdata.ladon.vo.system.TreeNodeVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.util.Assert;

import java.util.*;

/**
 * Created by oneape<oneape15@163.com>
 * Created 2019-07-09 11:18.
 * Modify:
 */
@Service
public class GroupService implements IGroupService {
    @Autowired
    private GroupMapper groupMapper;

    /**
     * 添加
     *
     * @param group Group
     * @return int
     */
    @Override
    public int addGroup(Group group) {
        Assert.isTrue(StringUtils.isNotBlank(group.getName()), "报表组名为空");
        int has = groupMapper.hasSameName(group.getParentId(), group.getName(), null);
        if (has > 0) {
            throw new BusinessException("同一级下面存在相同的报表组名称");
        }
        group.setLevel(getLevel(group.getParentId()));

        return groupMapper.insert(group);
    }

    private int getLevel(Long parentId) {
        if (parentId != null && parentId > 0) {
            Group parent = groupMapper.findById(parentId);
            if (parent == null) {
                throw new BusinessException("无效的父节点");
            }
            return parent.getLevel() + 1;

        }
        return 1;
    }

    /**
     * 修改报表组
     *
     * @param group Group
     * @return int
     */
    @Override
    public int editGroup(Group group) {
        Assert.isTrue(StringUtils.isNotBlank(group.getName()), "报表组名为空");
        Assert.isTrue(group.getId() != null, "报表组Id为空");
        int has = groupMapper.hasSameName(group.getParentId(), group.getName(), group.getId());
        if (has > 0) {
            throw new BusinessException("同一级下面存在相同的报表组名称");
        }
        group.setLevel(getLevel(group.getParentId()));

        return groupMapper.update(group);
    }

    /**
     * 删除报表组
     *
     * @param group Group
     * @return int
     */
    @Override
    public int delGroup(Group group) {
        Assert.isTrue(group.getId() != null, "报表组Id为空");
        // 是否存在子节点
        int size = groupMapper.hasChildren(group.getId());
        if (size > 0) {
            throw new BusinessException("该报表组下存在分组或报表,不能被删除");
        }

        return groupMapper.delete(group);
    }

    /**
     * 根据Id获取报表Id
     *
     * @param groupId Long
     * @return Group
     */
    @Override
    public Group getById(Long groupId) {
        return groupMapper.findById(groupId);
    }

    /**
     * 根据条件查询报表组
     *
     * @param params Map
     * @return List
     */
    @Override
    public List<Group> getByParams(Map<String, Object> params) {
        return groupMapper.getByParams(params);
    }

    /**
     * 查询子节点
     *
     * @param parentIds List
     * @return List
     */
    @Override
    public List<Group> getChildren(List<Long> parentIds) {
        if (parentIds == null || parentIds.size() == 0) {
            return null;
        }
        return groupMapper.getChildrenByPids(parentIds);
    }

    /**
     * 获取树型节点列表
     *
     * @return List<TreeNodeVo>
     */
    @Override
    public List<TreeNodeVo> getTreeNodes() {
        List<Group> groups = groupMapper.getAllSimpleGroup();
        // 最终的根节点Id为0, 所以这里只取0
        TreeNodeVo root = new TreeNodeVo("0", "根节点", "bars");

        if (groups != null && groups.size() >= 0) {

            Pair<Integer, Map<Integer, List<Group>>> pair = splitGroup(groups);
            // 从最深的分支开始向根节点递归
            Map<Long, List<TreeNodeVo>> preNode = new LinkedHashMap<>();
            for (int i = pair.getLeft(); i > 0; i--) {
                Map<Long, List<TreeNodeVo>> curNode = new LinkedHashMap<>();

                List<Group> tmp = pair.getRight().get(i);
                if (tmp == null) {
                    continue;
                }

                for (Group g : tmp) {
                    TreeNodeVo node = new TreeNodeVo(String.valueOf(g.getId()), g.getName(), g.getIcon());
                    if (preNode.containsKey(g.getId())) {
                        node.setChildren(preNode.get(g.getId()));
                        node.setLeaf(false);
                    } else {
                        node.setLeaf(true); // 没有子节点即为叶子节点
                    }
                    if (!curNode.containsKey(g.getParentId())) {
                        curNode.put(g.getParentId(), new ArrayList<>());
                    }
                    curNode.get(g.getParentId()).add(node);
                }

                preNode = curNode;
            }

            root.setChildren(preNode.get(0L));
        }
        List<TreeNodeVo> allNodes = new ArrayList<>();
        allNodes.add(root);
        return allNodes;
    }

    /**
     * 对列表以level进行分组
     *
     * @param groups List
     * @return map
     */
    @Override
    public Pair<Integer, Map<Integer, List<Group>>> splitGroup(List<Group> groups) {
        Map<Integer, List<Group>> levelMap = new HashMap<>();
        int maxLevel = 1;
        for (Group g : groups) {
            int level = g.getLevel();
            if (maxLevel < level) {
                maxLevel = level;
            }

            if (!levelMap.containsKey(level)) {
                levelMap.put(level, new ArrayList<>());
            }
            levelMap.get(level).add(g);
        }

        return new Pair<>(maxLevel, levelMap);
    }

    /**
     * 获取简单的报表组信息
     *
     * @return List
     */
    @Override
    public List<Group> getAllSimpleGroup() {
        return groupMapper.getAllSimpleGroup();
    }
}
